package main

import (
	"fmt"
	"math"
	"reflect"
	"runtime"
)

func eval(a, b int, opt string) (int, error) {
	switch opt {
	case "+":
		return a + b, nil
	case "-":
		return a - b, nil
	case "*":
		return a * b, nil
	case "/":
		//return a / b
		q, _ := div(a, b)
		return q, nil
	default:
		// 会中断执行
		//panic("unsupported operation：" + opt)
		return 0, fmt.Errorf("unsupported operation：%s", opt)
	}
}

func apply(op func(int, int) int, a, b int) int {
	// 获取该 func 的指针
	p := reflect.ValueOf(op).Pointer()
	//  获取 func 的 name
	opName := runtime.FuncForPC(p).Name()
	fmt.Printf("Calling function %s with args"+"(%d, %d)", opName, a, b)
	return op(a, b)
}

// 多返回值
// 1. 返回 error
func div(a, b int) (q, r int) {
	return a / b, a % b
}

// 返回多个值 可以起名字 （对于调用者没有区别，只有提示作用）
func pow(a, b int) int {
	return int(math.Pow(float64(a), float64(b)))
}

// 函数可以做为参数
// 可变参数列表
func sum(numbers ...int) int {
	s := 0
	for i := range numbers {
		s += numbers[i]
	}
	return s
}

func temp(a, b int) func(int) int {
	return func(a int) int {
		return 1
	}
}

func main() {
	if result, err := eval(3, 4, "x"); err != nil {
		fmt.Println("Error", err)
	} else {
		fmt.Println("Result::", result)
	}
	//q, r := div(13, 3)
	//fmt.Println(q, r)
	//fmt.Println(apply(func(a int, b int) int {
	//	return int(math.Pow(float64(a), float64(b)))
	//}, 3, 4))
	//fmt.Println(sum(1, 2, 3, 4, 5, 6, 7,8))
}

// 返回值类型 写在最后
// 可以返回多个值
// 函数可以作为参数
// 没有默认参数，函数重载、操作符重载...  只有可选参数列表
